﻿using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using Red.Controls.Extensions;
using Red.Controls.Shell;
using Red.Controls.ViewModels;

namespace Red.Controls.DataDriven
{
    public partial class MaterialDropDown : DropDown
    {
        #region Data

        private Brush _backgroundBrush;
        private DataItem _choicesItem;

        #endregion Data

        #region C-tor

        public MaterialDropDown()
        {
            InitializeComponent();

            DragBroadcaster.OnDragStarted += DragBroadcaster_OnDragStarted;
            DragBroadcaster.OnDragEnded += DragBroadcaster_OnDragEnded;
            _dataBox.Drop += DataBox_Drop;
        }

        #endregion C-tor

        #region Event handlers

        protected async override void OnPropertyChanged( DependencyPropertyChangedEventArgs e )
        {
            base.OnPropertyChanged( e );

            if ( e.Property == DataContextProperty )
            {
                var dataItem = e.NewValue as DataItem;
                if ( dataItem != null )
                {
                    _choicesItem = await dataItem.DigUpSubItemAsync( "$parent.$parent._choices" );
                    if ( _choicesItem != null )
                    {
                        _optionsList.ItemsSource = _choicesItem.Children;
                        await _choicesItem.RebuildAsync();
                    }
                }
            }
        }

        private async void OptionsList_SelectionChanged( object sender, System.Windows.Controls.SelectionChangedEventArgs e )
        {
            ListBox list = sender as ListBox;
            DataItem selected = list.SelectedItem as DataItem;
            
            if ( selected != null )
            {
                var nameItem = await selected.DigUpSubItemAsync( "name" );
                _dataBox.Text = nameItem.Value;
            }

            CloseDropDown( true );
        }

        private void OptionsList_Initialized( object sender, System.EventArgs e )
        {
            _optionsList.SetBinding( WidthProperty, new Binding( "ActualWidth" ) { Source = _dataBox } );
        }

        // DragBroadcaster events handling to indicate it's a target for dropping
        private void DragBroadcaster_OnDragStarted( object sender, IDataObject draggedData )
        {
            _backgroundBrush = _dataBox.Background;
            _dataBox.Background = Brushes.LightGreen;
        }

        private void DragBroadcaster_OnDragEnded( object sender, IDataObject draggedData )
        {
            _dataBox.Background = _backgroundBrush;
        }

        // Drop the resource
        private async void DataBox_Drop( object sender, DragEventArgs e )
        {
            IEnumerable<string> paths = e.Data.GetFormats().Select( format => e.Data.GetData( format ).ToString() );
            if ( paths.Any() )
            {
                _dataBox.Text = paths.First();
                if ( _choicesItem != null )
                {
                    await _choicesItem.RebuildAsync();
                }
            }
            else
            {
                RedMessageBox.Show( this, RedDialogType.Ok, "Property accepts just one value at a time." );
            }
        }

        #endregion Event handlers
    }
}
